﻿/*
 * Creado por SharpDevelop.
 * Usuario: jfacorro
 * Fecha: 30/05/2010
 * Hora: 17:18
 * 
 * Para cambiar esta plantilla use Herramientas | Opciones | Codificación | Editar Encabezados Estándar
 */
using System;
using System.Collections.Generic;
using System.Drawing;

namespace TimeMaker
{
	/// <summary>
	/// Description of FunctionGraph.
	/// </summary>
	public class FunctionGraph
	{
		private const int MAX_VALUES = 100;
		private const float INIT_MIN_VALUE = 0.5f;
		private const float INIT_MAX_VALUE = 0.5f;

		private Bitmap drawArea;
		private List<float> values = new List<float>(MAX_VALUES);
		private bool dirty = false;
		
		private float minValue = INIT_MIN_VALUE;
		private float maxValue = INIT_MAX_VALUE;
		private float deltaX;		
		
		public FunctionGraph(Bitmap drawArea)
		{
			this.drawArea = drawArea;
			this.deltaX = (float)this.drawArea.Width / (float)this.values.Capacity;
		}
		
		public void Add(float value)
		{
			if(this.values.Count == 0)
			{
				this.minValue = value;
				this.maxValue = value;
			}
			else
			{
				if(value < this.minValue)
				{
					this.minValue = value;
				}
				
				if(value > this.maxValue)
				{
					this.maxValue = value;
				}
			}

			if(this.values.Count >= this.values.Capacity)
			{
				this.values.RemoveAt(0);
			}

			this.values.Add(value);
			
			this.dirty = true;
		}
		
		public int Slope()
		{
			int count = this.values.Count;
			int slope = 0;
			
			if(count > 2)
			{
				if(this.values[count - 1] > this.values[count - 2])
				{
					slope = 1;
				}
				else if(this.values[count - 1] < this.values[count - 2])
				{
					slope = -1;
				}
				else
				{
					slope = 0;
				}
			}
			
			return slope;
		}
		
		public void Update()
		{
			if(this.dirty)
			{
				Graphics g = Graphics.FromImage(this.drawArea);
				
				g.Clear(Color.Black);
				
				Pen pen = new Pen(Color.Yellow, 1);
				
				for(int index = 0; index + 2 < this.values.Count; index++)
				{
					Point p1 = this.GetPoint(index);
					Point p2 = this.GetPoint(index + 1);
						
					g.DrawLine(pen, p1, p2);
				}

				Point zeroBegin = this.GetPoint(0, 0);
				Point zeroEnd = new Point(this.drawArea.Width, zeroBegin.Y);

				g.DrawLine(pen, zeroBegin, zeroEnd);
				Font font = new Font(FontFamily.GenericMonospace, 10.0f, FontStyle.Regular, GraphicsUnit.Pixel);
				
				// Draw max and min values
				g.DrawString(this.minValue.ToString(), font, Brushes.White, 0.0f, 20.0f);
				g.DrawString(this.maxValue.ToString(), font, Brushes.White, 0.0f, 10.0f);

				this.dirty = false;
			}
		}
		
		private Point GetPoint(int index)
		{
			float value = this.values[index];

			int x = Convert.ToInt32(this.deltaX * (float)index);
			
			return this.GetPoint(value, x);
		}
		
		private Point GetPoint(float value, int x)
		{
			int y = 0;
			float diff = this.maxValue - this.minValue;

			if(diff > 0)
			{
				y = Convert.ToInt32(((float)this.drawArea.Height / (float)diff) * (this.maxValue-value));
			}

			return new Point(x, y);			
		}
	}
}
